====== Langage de programmation Common Lisp ======

[[wpfr>Common_Lisp|Common Lisp]] est un langage de programmation de la famille des Lisp, multi-paradigmes, compilé, typé dynamiquement. 

Common Lisp est une spécification standardisée par l'ANSI en 1984, et compte plusieurs implémentations. SBCL (Steel Bank Common Lisp) est l'implémentation open-source la plus populaire.

Aujourd'hui, Common Lisp est toujours utilisé dans l'industrie dans beaucoup de domaines: informatique quantique, analyses financières, systèmes de planification, logiciels de modélisation, musique assistée par ordinateur, assistants de preuves, applications web…

Les premières origines des langages Lisp remontent aux années 60 suivant les travaux de John McCarthy. 

On distinguera plusieurs dialectes de la famille des Lisp: Common Lisp, la famille des Scheme, Clojure, et les langages avec une syntaxe Lisp qui transpilent dans un autre langage hôte (tel que LFE: Lisp-Flavored Erlang).

===== Programmer en Common Lisp =====

====== Installation ======

Il vous faut installer une implémentation. Sous Ubuntu, plusieurs sont disponibles, mais nous utiliserons sbcl:

<code bash>
$ apt install sbcl rlwrap
</code>

====== Première utilisation ======

SBCL contient un interpréteur de commandes et un compilateur. Pour évoquer l'interpréteur et obtenir un "REPL" (Read Eval Print Loop) basique en ligne de commande, appelez ''sbcl''.

Mais pour obtenir une interface plus ergonomique, utilisez l'interface à readline avec ''rlwrap'' (readline wrapper):

<code bash>
$ rlwrap sbcl
his is SBCL 2.1.5, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* 
</code>

Vous pouvez entrer du code directement dans l'interpréteur de commandes. Par exemple:

<code bash>
* (+ 40 2)
;; => 42
* (defun hello (name) (format t "Salut ~a !" name))
;; => HELLO
* (hello "moi")
;; => "Salut moi !"
* (mapcar #'hello (list "moi" "toi"))
;; => Salut moi !Salut toi !
;; (NIL NIL)
</code>

Bravo ! Vous venez de voir que:

  * Lisp utilise une notation préfixée. Au lieu d'appeler "2 + 2", soit une opérande, une fonction, une opérande, on appelle la fonction d'abord et les opérandes à la suite, soit "(+ 2 2)".
  * les appels de fonction se font en ouvrant une parenthèse et en la refermant après les arguments: ''(+ 40 1 1)''.
  * on crée une fonction avec ''defun'': ''(defun hello () …)'', on appelle notre fonction avec ''(hello …)''.
  * ''format t …'' permet d'écrire sur la sortie standard (''t''). ''print'' existe mais ''format'' est beaucoup plus modulaire.
  * on peut référencer une fonction avec la notation ''#\''': ''#'hello''. Les fonctions sont des objets de premier ordre. On peut avoir des variables et des fonctions avec le même nom, elles ne se marcheront pas dessus.
  * on peut appliquer une fonction à plusieurs arguments à la suite: ''mapcar'' (souvent "map" dans les langages plus récents).

Et, enfin: la structure des expressions en Lisp est la même que la structure utilisée pour représenter des listes: les parenthèses. ''(list 40 2)'' est une liste, '''(40 2)'' est la même liste écrite avec un raccourci, et ''(+ 40 2)'' a la même structure qu'une liste. Mais quand on l'évalue, on appelle la fonction ''+'' avec deux opérandes. Ainsi, un programme Lisp est, dans la syntaxe Lisp, simplement une liste de listes imbriquées. 

====== Avec un fichier texte ======

La grande force de Common Lisp est son environnement de développement dynamique, mais on peut commencer de la manière la plus simple possible, en écrivant du code dans un fichier texte (extension .lisp) avec n'importe quel éditeur. S'il indente automatiquement la ligne et s'il permet de visualiser les parenthèses ouvrantes et fermantes, tant mieux.

Créez un fichier "hello.lisp" avec votre éditeur de texte préféré et lancez SBCL.

<code bash>
$ touch hello.lisp
$ rlwrap sbcl
;;
*
</code>

Dans votre éditeur, ajoutez la fonction ''hello'' vue plus haut.

Depuis SBCL, nous pouvons charger et exécuter le code de ce fichier avec la fonction ''load'':

<code bash>
* (load "hello.lisp")
T
</code>

Le ''T'' veut dire "true", que tout s'est bien passé. Vous pouvez maintenant utiliser la fonction qui a été définie dans le fichier externe.

====== Utilisation en script ======

Presque toutes les implémentations, dont SBCL, permettent de créer un fichier binaire exécutable. Mais nous pouvons également lancer notre programme sans cette étape, simplement à partir des sources.

Dans votre fichier "hello.lisp", ajoutez quelques commandes qui produisent un résultat. Par exemple:

<code lisp>
(defun hello (name)
  "Dit salut à NAME."
  (format t "Salut ~a !" name))

(print "Je vais dire salut…")
(hello "you")
</code>

Vous pouvez lancer ce script depuis le terminal avec ''sbcl --script'':

<code bash>
$ sbcl --script hello.lisp
"Je vais dire salut…" Salut you !
$
</code>

On observe que ''print'' a affiché les guillemets mais pas ''format … ~a''.

Vous pouvez également utiliser ''sbcl --load hello.lisp'', et dans ce cas vous obtiendrez un REPL après exécution du fichier, ce qui vous permet de continuer à travailler.
===== Les éditeurs =====

Pendant longtemps, les seuls *bons* éditeurs disponibles étaient [[emacs|Emacs]] et son plugin Slime ainsi que l'IDE LispWorks, qui vient avec l'implémentation du même nom, mais qui est propriétaire. Aujourd'hui, il existe de bons modules pour des éditeurs populaires. Nous vous référons à: https://lispcookbook.github.io/cl-cookbook/editor-support.html
